/*
 * GameControllerServerView.java
 */
package gamecontrollerserver;

import ButtonBeans.ButtonBean;
import ButtonBeans.ControllerElement;
import ButtonBeans.JoystickBean;
import ButtonBeans.MouseJoystickBean;
import ButtonBeans.RoundButtonBean;
import ControllerSerialization.ControllerSerializer;
import EventProcessor.EventProcessor;
import GameControllerExceptions.InvalidButtonCountException;
import Panels.GlassPanel;
import Panels.RightClickOptionAndDeletePanel;
import ServerPanels.SaveOptionHandler;
import buttonOptions.NormalButtonOptionFrame;
import buttonOptions.RoundButtonOptionFrame;
import buttonOptions.StaticControllerOptionFrame;
import constants.GameControllerServerConstants;
import GameControllerExceptions.InvalidControllerException;
import Helper.BrowserControl;
import Helper.ErrorHandler;
import Helper.ExtensionFileFilter;
import Panels.RightClickDeletePanel;
import controllerButtons.MouseJoystickButton;
import controllerButtons.StaticControllerButton;
import controllerButtons.NormalControllerButton;
import controllerButtons.RoundControllerButton;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.Task;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.List;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;
import org.simpleframework.http.core.Container;
import org.simpleframework.transport.connect.Connection;
import org.simpleframework.transport.connect.SocketConnection;

/**
 * The application's main frame.
 */
public class GameControllerServerView extends FrameView {

    boolean serverStarted = false;
    ServerHandler serverHandler;
    int x = 0;
    int y = 0;
    int lx = 0;
    int ly = 0;
    int cx = 0;
    int cy = 0;
    boolean hasMouseReleased = false;
    boolean enteredLeft = false;
    Container container;
    Connection connection;
    ControllerSerializer controllerSerializer = ControllerSerializer.getInstance();
    EventProcessor eventProcessor = EventProcessor.getInstance();
    GlassPanel overlayGameControllerPanel, overlayButtonContainerPanel;
    long roundButtonTimeFirst=0, roundButtonTimeSecond=0;
    long normalButtonTimeFirst=0, normalButtonTimeSecond=0;
    long staticControllerTimeFirst=0, staticControllerTimeSecond;
    long mouseControllerTimeFirst=0, mouseControllerTimeSecond=0;
    org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(gamecontrollerserver.GameControllerServerApp.class).getContext().getResourceMap(GameControllerServerView.class);
        
    public GameControllerServerView(SingleFrameApplication app) {
        super(app);

        initComponents();
        setLocalIPToTextField();


        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {

            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String) (evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer) (evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
        jTextFieldPort.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
            }

            public void focusLost(FocusEvent e) {
                try {
                    Integer.parseInt(jTextFieldPort.getText());
                } catch (NumberFormatException ex) {
                    ErrorHandler.invalidPortMessage(mainPanel);
                }

            }
        });
        getFrame().setResizable(false);
        getFrame().setLocation(Toolkit.getDefaultToolkit().getScreenSize().width / 4, Toolkit.getDefaultToolkit().getScreenSize().height / 4);
      
        jPanelMenuPlaceholder.addMouseListener(new MouseListener() {

            public void mouseClicked(MouseEvent e) {
            ErrorHandler.menuPlaceHolderMessage(mainPanel);

            }

            public void mousePressed(MouseEvent e) {
            }

            public void mouseReleased(MouseEvent e) {
            }

            public void mouseEntered(MouseEvent e) {
            }

            public void mouseExited(MouseEvent e) {
            }
        });
    }

    private void setLocalIPToTextField() {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            jTextFieldLocalIP.setText(addr.getHostAddress());
        } catch (UnknownHostException ex) {
            Logger.getLogger(GameControllerServerView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = GameControllerServerApp.getApplication().getMainFrame();
            aboutBox = new GameControllerServerAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        GameControllerServerApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jTextFieldLocalIP = new javax.swing.JTextField();
        jLabelLocalIP = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jTextFieldPort = new javax.swing.JTextField();
        jButtonStartServer = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        jPanelGameController = new javax.swing.JLayeredPane();
        jPanelMenuPlaceholder = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jPanelButtonContainer = new javax.swing.JLayeredPane();
        jButtonNormalButton = new javax.swing.JButton();
        jButtonStaticController = new javax.swing.JButton();
        jButtonRoundButton = new javax.swing.JButton();
        jButtonMouseJoystick = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                mainPanelMouseDragged(evt);
            }
        });

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(gamecontrollerserver.GameControllerServerApp.class).getContext().getResourceMap(GameControllerServerView.class);
        jPanel1.setBackground(resourceMap.getColor("jPanel1.background")); // NOI18N
        jPanel1.setName("jPanel1"); // NOI18N

        jTextFieldLocalIP.setText(resourceMap.getString("jTextFieldLocalIP.text")); // NOI18N
        jTextFieldLocalIP.setEnabled(false);
        jTextFieldLocalIP.setName("jTextFieldLocalIP"); // NOI18N

        jLabelLocalIP.setText(resourceMap.getString("jLabelLocalIP.text")); // NOI18N
        jLabelLocalIP.setName("jLabelLocalIP"); // NOI18N

        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N

        jTextFieldPort.setText(resourceMap.getString("jTextFieldPort.text")); // NOI18N
        jTextFieldPort.setDragEnabled(false);
        jTextFieldPort.setName("jTextFieldPort"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(gamecontrollerserver.GameControllerServerApp.class).getContext().getActionMap(GameControllerServerView.class, this);
        jButtonStartServer.setAction(actionMap.get("onStartServerClicked")); // NOI18N
        jButtonStartServer.setIcon(resourceMap.getIcon("jButtonStartServer.icon")); // NOI18N
        jButtonStartServer.setName("jButtonStartServer"); // NOI18N

        jLabel3.setIcon(resourceMap.getIcon("jLabel3.icon")); // NOI18N
        jLabel3.setText(resourceMap.getString("jLabel3.text")); // NOI18N
        jLabel3.setName("jLabel3"); // NOI18N
        jLabel3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabel3MouseClicked(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jLabelLocalIP)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jTextFieldLocalIP, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 147, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(34, 34, 34)
                .add(jLabel1)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jTextFieldPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 54, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(18, 18, 18)
                .add(jButtonStartServer)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 252, Short.MAX_VALUE)
                .add(jLabel3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 62, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .add(20, 20, 20)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabelLocalIP)
                    .add(jTextFieldLocalIP, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel1)
                    .add(jTextFieldPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jButtonStartServer))
                .addContainerGap())
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .add(11, 11, 11)
                .add(jLabel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(9, 9, 9))
        );

        jPanelGameController.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jPanelGameController.setName("jPanelGameController"); // NOI18N

        jPanelMenuPlaceholder.setBackground(resourceMap.getColor("jPanelMenuPlaceholder.background")); // NOI18N
        jPanelMenuPlaceholder.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanelMenuPlaceholder.setName("jPanelMenuPlaceholder"); // NOI18N
        jPanelMenuPlaceholder.setLayout(null);

        jLabel2.setIcon(resourceMap.getIcon("jLabel2.icon")); // NOI18N
        jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N
        jPanelMenuPlaceholder.add(jLabel2);
        jLabel2.setBounds(10, 10, 80, 40);

        jPanelMenuPlaceholder.setBounds(375, 5, 100, 50);
        jPanelGameController.add(jPanelMenuPlaceholder, javax.swing.JLayeredPane.DEFAULT_LAYER);

        jPanelButtonContainer.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanelButtonContainer.setName("jPanelButtonContainer"); // NOI18N

        jButtonNormalButton.setBackground(resourceMap.getColor("jButtonNormalButton.background")); // NOI18N
        jButtonNormalButton.setText(resourceMap.getString("jButtonNormalButton.text")); // NOI18N
        jButtonNormalButton.setName("jButtonNormalButton"); // NOI18N
        jButtonNormalButton.setOpaque(true);
        jButtonNormalButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jButtonNormalButtonMouseReleased(evt);
            }
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButtonNormalButtonMouseClicked(evt);
            }
        });
        jButtonNormalButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jButtonNormalButtonMouseDragged(evt);
            }
        });
        jButtonNormalButton.setBounds(10, 20, 120, 29);
        jPanelButtonContainer.add(jButtonNormalButton, javax.swing.JLayeredPane.DEFAULT_LAYER);

        jButtonStaticController.setBackground(resourceMap.getColor("jButtonStaticController.background")); // NOI18N
        jButtonStaticController.setIcon(new javax.swing.ImageIcon(getClass().getResource("/gamecontrollerserver/resources/arrow_controller.png"))); // NOI18N
        jButtonStaticController.setText(resourceMap.getString("jButtonStaticController.text")); // NOI18N
        jButtonStaticController.setMaximumSize(new java.awt.Dimension(120, 120));
        jButtonStaticController.setMinimumSize(new java.awt.Dimension(120, 120));
        jButtonStaticController.setName("jButtonStaticController"); // NOI18N
        jButtonStaticController.setOpaque(true);
        jButtonStaticController.setSize(new java.awt.Dimension(120, 120));
        jButtonStaticController.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jButtonStaticControllerMouseReleased(evt);
            }
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButtonStaticControllerMouseClicked(evt);
            }
        });
        jButtonStaticController.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jButtonStaticControllerButtonDragged(evt);
            }
        });
        jButtonStaticController.setBounds(10, 70, 120, 120);
        jPanelButtonContainer.add(jButtonStaticController, javax.swing.JLayeredPane.DEFAULT_LAYER);

        jButtonRoundButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/gamecontrollerserver/resources/roundButton.png"))); // NOI18N
        jButtonRoundButton.setText(resourceMap.getString("jButtonRoundButton.text")); // NOI18N
        jButtonRoundButton.setBorderPainted(false);
        jButtonRoundButton.setName("jButtonRoundButton"); // NOI18N
        jButtonRoundButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jButtonRoundButtonMouseReleased(evt);
            }
        });
        jButtonRoundButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jButtonRoundButtonMouseDragged(evt);
            }
        });
        jButtonRoundButton.setBounds(10, 210, 70, 73);
        jPanelButtonContainer.add(jButtonRoundButton, javax.swing.JLayeredPane.DEFAULT_LAYER);

        jButtonMouseJoystick.setIcon(resourceMap.getIcon("jButtonMouseJoystick.icon")); // NOI18N
        jButtonMouseJoystick.setText(resourceMap.getString("jButtonMouseJoystick.text")); // NOI18N
        jButtonMouseJoystick.setBorderPainted(false);
        jButtonMouseJoystick.setName("jButtonMouseJoystick"); // NOI18N
        jButtonMouseJoystick.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jButtonMouseJoystickReleased(evt);
            }
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButtonMouseJoystickClicked(evt);
            }
        });
        jButtonMouseJoystick.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jButtonMouseJoystickDragged(evt);
            }
        });
        jButtonMouseJoystick.setBounds(150, 10, 120, 120);
        jPanelButtonContainer.add(jButtonMouseJoystick, javax.swing.JLayeredPane.DEFAULT_LAYER);

        org.jdesktop.layout.GroupLayout mainPanelLayout = new org.jdesktop.layout.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(jPanelGameController, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 480, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(jPanelButtonContainer, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 286, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(mainPanelLayout.createSequentialGroup()
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(18, 18, 18)
                .add(mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanelGameController, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 320, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jPanelButtonContainer, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 345, Short.MAX_VALUE))
                .addContainerGap())
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        jMenuItem1.setAction(actionMap.get("onNewControllerClicked")); // NOI18N
        jMenuItem1.setText("New Controller");
        jMenuItem1.setActionCommand(resourceMap.getString("jMenuItem1.actionCommand")); // NOI18N
        jMenuItem1.setName("jMenuItem1"); // NOI18N
        fileMenu.add(jMenuItem1);

        jMenuItem2.setAction(actionMap.get("onSaveControllerClicked")); // NOI18N
        jMenuItem2.setText("Save Controller");
        jMenuItem2.setName("jMenuItem2"); // NOI18N
        fileMenu.add(jMenuItem2);

        jMenuItem3.setAction(actionMap.get("onLoadControllerClicked")); // NOI18N
        jMenuItem3.setText("Load Controller");
        jMenuItem3.setName("jMenuItem3"); // NOI18N
        fileMenu.add(jMenuItem3);

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        org.jdesktop.layout.GroupLayout statusPanelLayout = new org.jdesktop.layout.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(statusPanelSeparator, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 820, Short.MAX_VALUE)
            .add(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(statusMessageLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 780, Short.MAX_VALUE)
                .add(statusAnimationLabel)
                .addContainerGap())
            .add(org.jdesktop.layout.GroupLayout.TRAILING, statusPanelLayout.createSequentialGroup()
                .addContainerGap(622, Short.MAX_VALUE)
                .add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(52, 52, 52))
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(statusPanelLayout.createSequentialGroup()
                .add(statusPanelSeparator, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                        .add(statusMessageLabel)
                        .add(statusAnimationLabel))
                    .add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    private void mainPanelMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mainPanelMouseDragged
//        // TODO add your handling code here:
    }//GEN-LAST:event_mainPanelMouseDragged

    private void jButtonNormalButtonMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonNormalButtonMouseDragged

        if (serverStarted) {
            return;
        }

        Component move = (Component) evt.getSource();
        lx = evt.getX() + move.getX() - cx;
        ly = evt.getY() + move.getY() - cy;

        move.setLocation(lx, ly);


        if ((lx < 0 - jButtonNormalButton.getWidth()) && !enteredLeft) {
            enteredLeft = true;
            NormalControllerButton newButton = new NormalControllerButton();
            newButton.setLocation(10, 10);
            newButton.setOpaque(((JButton) move).isOpaque());
            Color newColor = new Color(0, 0, 0, 255);
            newButton.setColor(newColor);
            newButton.setSize(move.getSize());
            newButton.setText(((JButton) move).getText());
            newButton.setButtonToPress("A");
            newButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                @Override
                public void mouseDragged(java.awt.event.MouseEvent evt) {
                    normalButtonOnGameControllerDragges(evt);
                }
            });
            newButton.addMouseListener(new java.awt.event.MouseListener() {

                public void mouseClicked(MouseEvent e) {
                    normalButtonOnGameControllerClicked(e);
                }

                public void mousePressed(MouseEvent e) {
                }

                public void mouseReleased(MouseEvent e) {
                }

                public void mouseEntered(MouseEvent e) {
                }

                public void mouseExited(MouseEvent e) {
                }
            });
            jPanelGameController.add(newButton, 1);
            jPanelGameController.repaint();

        }



    }//GEN-LAST:event_jButtonNormalButtonMouseDragged
    private void normalButtonOnGameControllerClicked(java.awt.event.MouseEvent evt) {
        if (serverStarted) {
            return;
        }

        //Check if doubleclick (issue because of other systems where no rightclick gets recognized)
         long timeDifBetweenClicks = 301;
        if (evt.getButton() == MouseEvent.BUTTON1) {
            if (normalButtonTimeFirst == 0) {
                normalButtonTimeFirst = System.currentTimeMillis();
            } else if (normalButtonTimeFirst != 0 && normalButtonTimeSecond == 0) {
                normalButtonTimeSecond = System.currentTimeMillis();
                timeDifBetweenClicks = normalButtonTimeSecond - normalButtonTimeFirst;
                System.err.println("Time between:" + timeDifBetweenClicks);
                normalButtonTimeFirst = 0;
                normalButtonTimeSecond = 0;
            }
        }



        if (evt.getButton() == MouseEvent.BUTTON3 || timeDifBetweenClicks<=300) {

            if (!GameControllerServerConstants.isOptionInUse) {
                GameControllerServerConstants.isOptionInUse = true;
                NormalButtonOptionFrame optionPanel = new NormalButtonOptionFrame(evt, jPanelGameController);
                optionPanel.setAlwaysOnTop(true);

                optionPanel.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
                    public void windowClosing(WindowEvent winEvt) {
                        GameControllerServerConstants.isOptionInUse = false;
                    }
                });
                RightClickOptionAndDeletePanel menu = new RightClickOptionAndDeletePanel(evt, jPanelGameController, optionPanel);
                menu.show(evt.getComponent(), evt.getX(), evt.getY());
            }

        }
    }

    private void normalButtonOnGameControllerDragges(java.awt.event.MouseEvent evt) {

        if (serverStarted) {
            return;
        }
        if(evt.getSource() instanceof RoundControllerButton){
            roundButtonTimeFirst =0;
            roundButtonTimeSecond =0;
            staticControllerTimeFirst =0;
            staticControllerTimeSecond =0;
            normalButtonTimeFirst =0;
            normalButtonTimeSecond =0;
            mouseControllerTimeFirst =0;
            mouseControllerTimeSecond =0;
        }

        Component move = (Component) evt.getSource();
        
        lx = evt.getX() + move.getX() - cx;
        ly = evt.getY() + move.getY() - cy;

        if(lx<0){
            lx=0;
        }else if(lx> jPanelGameController.getWidth() - move.getWidth()){
            lx = jPanelGameController.getWidth() - move.getWidth();
        }

        if(ly<0){
            ly=0;
        }else if(ly>jPanelGameController.getHeight() - move.getHeight()){
            ly = jPanelGameController.getHeight() - move.getHeight();
        }

        if (lx >= 0 && (lx <= jPanelGameController.getWidth() - move.getWidth()) && (ly <= jPanelGameController.getHeight() - move.getHeight()) && ly >= 0) {
            if ((lx <= 375 - move.getWidth()) || (lx <= 375 - move.getWidth() && ly >= 55) || (lx >= 0 && ly >= 55)) {
                move.setLocation(lx, ly);
            }
        }

    }


    private void jButtonNormalButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonNormalButtonMouseClicked
        Component move = (Component) evt.getSource();

        Component[] components = jPanelGameController.getComponents();
        boolean isOnLeftSite = false;
        for (int i = 0; i < components.length; i++) {
            if (components[i].equals(move)) {
                isOnLeftSite = true;
            }
        }


    }//GEN-LAST:event_jButtonNormalButtonMouseClicked

    private void jButtonNormalButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonNormalButtonMouseReleased
        hasMouseReleased = true;
        enteredLeft = false;
        Component move = (Component) evt.getSource();
        move.setLocation(5, 25);
    }//GEN-LAST:event_jButtonNormalButtonMouseReleased

    private void jButtonStaticControllerButtonDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonStaticControllerButtonDragged

        if (serverStarted) {
            return;
        }

        Component move = (Component) evt.getSource();
        lx = evt.getX() + move.getX() - cx;
        ly = evt.getY() + move.getY() - cy;

        move.setLocation(lx, ly);


        if ((lx < 0 - jButtonStaticController.getWidth()) && !enteredLeft) {
            enteredLeft = true;
            StaticControllerButton newButton = new StaticControllerButton();
            newButton.setLocation(10, 10);
            newButton.setSize(move.getSize());
            newButton.setText(((JButton) move).getText());
            newButton.setOpaque(((JButton) move).isOpaque());
            Color newColor = new Color(0, 0, 0, 255);
            newButton.setColor(newColor);
            newButton.setUpButton("UP");
            newButton.setDownButton("DOWN");
            newButton.setLeftButton("LEFT");
            newButton.setRightButton("RIGHT");
            newButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                @Override
                public void mouseDragged(java.awt.event.MouseEvent evt) {
                    normalButtonOnGameControllerDragges(evt);
                }
            });
            newButton.addMouseListener(new java.awt.event.MouseListener() {

                public void mouseClicked(MouseEvent e) {
                    jButtonStaticControllerMouseClicked(e);
                }

                public void mousePressed(MouseEvent e) {
                }

                public void mouseReleased(MouseEvent e) {
                }

                public void mouseEntered(MouseEvent e) {
                }

                public void mouseExited(MouseEvent e) {
                }
            });
            jPanelGameController.add(newButton);
            jPanelGameController.repaint();


        }
    }//GEN-LAST:event_jButtonStaticControllerButtonDragged

    private void jButtonStaticControllerMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonStaticControllerMouseReleased

        hasMouseReleased = true;
        enteredLeft = false;
        Component move = (Component) evt.getSource();
        move.setLocation(10, 70);
    }//GEN-LAST:event_jButtonStaticControllerMouseReleased

    private void jButtonStaticControllerMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonStaticControllerMouseClicked
        if (serverStarted) {
            return;
        }

        boolean isOnLeftSide = false;

        for (Component com : jPanelGameController.getComponents()) {
            if (com.equals(evt.getSource())) {
                isOnLeftSide = true;
            }
        }
        //Check if doubleclick (issue because of other systems where no rightclick gets recognized)
         long timeDifBetweenClicks = 301;
        if (evt.getButton() == MouseEvent.BUTTON1) {
            if (staticControllerTimeFirst == 0) {
                staticControllerTimeFirst = System.currentTimeMillis();
            } else if (staticControllerTimeFirst != 0 && staticControllerTimeSecond == 0) {
                staticControllerTimeSecond = System.currentTimeMillis();
                timeDifBetweenClicks = staticControllerTimeSecond - staticControllerTimeFirst;
                System.err.println("Time between:" + timeDifBetweenClicks);
                staticControllerTimeFirst = 0;
                staticControllerTimeSecond = 0;
            }
        }


        if ((evt.getButton() == MouseEvent.BUTTON3 && isOnLeftSide) || (timeDifBetweenClicks<=300 && isOnLeftSide)) {
            if (!GameControllerServerConstants.isOptionInUse) {
                GameControllerServerConstants.isOptionInUse = true;
                StaticControllerOptionFrame optionPanel = new StaticControllerOptionFrame(evt, jPanelGameController);
                optionPanel.setAlwaysOnTop(true);
                optionPanel.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
                    public void windowClosing(WindowEvent winEvt) {
                        GameControllerServerConstants.isOptionInUse = false;
                    }
                });
                RightClickOptionAndDeletePanel menu = new RightClickOptionAndDeletePanel(evt, jPanelGameController, optionPanel);
                menu.show(evt.getComponent(), evt.getX(), evt.getY());
            }


        }
    }//GEN-LAST:event_jButtonStaticControllerMouseClicked

    private void jButtonRoundButtonMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonRoundButtonMouseDragged

        if (serverStarted) {
            return;
        }
        Component move = (Component) evt.getSource();
        lx = evt.getX() + move.getX() - cx;
        ly = evt.getY() + move.getY() - cy;

        move.setLocation(lx, ly);


        if ((lx < 0 - jButtonRoundButton.getWidth()) && !enteredLeft) {
            enteredLeft = true;
            RoundControllerButton newButton = new RoundControllerButton("A");
            newButton.setLocation(10, 10);
            newButton.setSize(new Dimension(73, 73));//move.getSize());
            Color newColor = new Color(0, 0, 0, 255);
            newButton.setColor(newColor);
            newButton.setButtonToPress("A");
            newButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                @Override
                public void mouseDragged(java.awt.event.MouseEvent evt) {
                  
                    normalButtonOnGameControllerDragges(evt);
                }
            });
            newButton.addMouseListener(new java.awt.event.MouseListener() {

                public void mouseClicked(MouseEvent e) {
                    jButtonRoundButtonMouseClicked(e);
                }

                public void mousePressed(MouseEvent e) {
                }

                public void mouseReleased(MouseEvent e) {
                }

                public void mouseEntered(MouseEvent e) {
                }

                public void mouseExited(MouseEvent e) {
                }
            });
            jPanelGameController.add(newButton);
            jPanelGameController.repaint();


        }
    }//GEN-LAST:event_jButtonRoundButtonMouseDragged

    private void jButtonRoundButtonMouseClicked(java.awt.event.MouseEvent evt) {
        if (serverStarted) {
            return;
        }
       long timeDifBetweenClicks=301;
        if (evt.getButton() == MouseEvent.BUTTON1){
            if (roundButtonTimeFirst == 0) {
                roundButtonTimeFirst = System.currentTimeMillis();
            } else if (roundButtonTimeFirst != 0 && roundButtonTimeSecond == 0) {
                roundButtonTimeSecond = System.currentTimeMillis();
                timeDifBetweenClicks = roundButtonTimeSecond - roundButtonTimeFirst;
                System.err.println("Time between:" + timeDifBetweenClicks);
                roundButtonTimeFirst = 0;
                roundButtonTimeSecond = 0;
       }
        }
      
        if (evt.getButton() == MouseEvent.BUTTON3 || timeDifBetweenClicks<=300) {
            if (!GameControllerServerConstants.isOptionInUse) {
                GameControllerServerConstants.isOptionInUse = true;
                RoundButtonOptionFrame optionPanel = new RoundButtonOptionFrame(evt, jPanelGameController);
                optionPanel.setAlwaysOnTop(true);
                optionPanel.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
                    public void windowClosing(WindowEvent winEvt) {
                        GameControllerServerConstants.isOptionInUse = false;
                    }
                });

                RightClickOptionAndDeletePanel menu = new RightClickOptionAndDeletePanel(evt, jPanelGameController, optionPanel);
                menu.show(evt.getComponent(), evt.getX(), evt.getY());
            }

        }
    }

    private void jButtonRoundButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonRoundButtonMouseReleased
        hasMouseReleased = true;
        enteredLeft = false;
        Component move = (Component) evt.getSource();
        move.setLocation(7, 205);
    }//GEN-LAST:event_jButtonRoundButtonMouseReleased

    private void jButtonMouseJoystickDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonMouseJoystickDragged
          if (serverStarted) {
            return;
        }
        Component move = (Component) evt.getSource();
        lx = evt.getX() + move.getX() - cx;
        ly = evt.getY() + move.getY() - cy;

        move.setLocation(lx, ly);


        if ((lx < 0 - jButtonMouseJoystick.getWidth()) && !enteredLeft) {
            enteredLeft = true;
            MouseJoystickButton newButton = new MouseJoystickButton();
            newButton.setLocation(10, 10);
            newButton.setSize(move.getSize());
            newButton.setBorderPainted(false);
            newButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
           
       
                @Override
                public void mouseDragged(java.awt.event.MouseEvent evt) {     
                    normalButtonOnGameControllerDragges(evt);
                }
            });
                newButton.addMouseListener(new java.awt.event.MouseListener() {

                public void mouseClicked(MouseEvent e) {
                    jButtonMouseJoystickClicked(e);
                }

                public void mousePressed(MouseEvent e) {
                }

                public void mouseReleased(MouseEvent e) {
                }

                public void mouseEntered(MouseEvent e) {
                }

                public void mouseExited(MouseEvent e) {
                }
            });
            jPanelGameController.add(newButton);
            jPanelGameController.repaint();


        }
    }//GEN-LAST:event_jButtonMouseJoystickDragged

    private void jButtonMouseJoystickReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonMouseJoystickReleased
        hasMouseReleased = true;
        enteredLeft = false;
        Component move = (Component) evt.getSource();
        move.setLocation(150, 30);
    }//GEN-LAST:event_jButtonMouseJoystickReleased

    private void jButtonMouseJoystickClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButtonMouseJoystickClicked
            if (serverStarted) {
            return;
        }

        //Check if doubleclick (issue because of other systems where no rightclick gets recognized)
         long timeDifBetweenClicks = 301;
        if (evt.getButton() == MouseEvent.BUTTON1) {
            if (mouseControllerTimeFirst == 0) {
                mouseControllerTimeFirst = System.currentTimeMillis();
            } else if (mouseControllerTimeFirst != 0 && mouseControllerTimeSecond == 0) {
                mouseControllerTimeSecond = System.currentTimeMillis();
                timeDifBetweenClicks = mouseControllerTimeSecond - mouseControllerTimeFirst;
                System.err.println("Time between:" + timeDifBetweenClicks);
                mouseControllerTimeFirst = 0;
                mouseControllerTimeSecond = 0;
            }
        }

        if (evt.getButton() == MouseEvent.BUTTON3 || timeDifBetweenClicks<=300) {
            if (!GameControllerServerConstants.isOptionInUse) {
                GameControllerServerConstants.isOptionInUse = true;
                

               RightClickDeletePanel menu = new RightClickDeletePanel(evt, jPanelGameController);
                menu.show(evt.getComponent(), evt.getX(), evt.getY());
            }

        }
    }//GEN-LAST:event_jButtonMouseJoystickClicked

    private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel3MouseClicked
        // TODO add your handling code here:
         BrowserControl.openUrl("http://itunes.apple.com/us/app/custom-controller/id441419191");
    }//GEN-LAST:event_jLabel3MouseClicked

    @Action
    public Task onStartServerClicked() {

        if (serverStarted) {
            enableUI();
            
        } else {
            try {
                Integer.parseInt(jTextFieldPort.getText());
            } catch (NumberFormatException ex) {
                ErrorHandler.invalidPortMessage(mainPanel);
                return null;

            }

            if (jPanelGameController.getComponentCount() < 2) {
                ErrorHandler.notEnoughButtonsMessage(mainPanel);
                return null;
            } else {

                disableUI();
                
            }


        }

        return new OnStartServerClickedTask(getApplication());
    }

    private class OnStartServerClickedTask extends org.jdesktop.application.Task<Object, Void> {

        OnStartServerClickedTask(org.jdesktop.application.Application app) {
            super(app);
        }

        @Override
        protected Object doInBackground() {

            if (serverStarted) {
                //Start
                try {
                    controllerSerializer.savaController(jPanelGameController, System.getProperty("user.home") + "/" + "tmp.xml");
                    controllerSerializer.loadController(new File(System.getProperty("user.home") + "/tmp.xml"));
                }catch(InvalidButtonCountException ex){
                    ErrorHandler.notEnoughButtonsMessage(mainPanel);
                    enableUI();
                    return null;
                } catch (InvalidControllerException ex) {
                    ErrorHandler.invalidControllerDataMessage(mainPanel);
                    enableUI();
                    return null;
                }

                try {
                    eventProcessor.mapIdsToButtons(controllerSerializer.getButtonList());
                    container = new SimpleHTTPHandler();
                    connection = new SocketConnection(container);

                    int port = Integer.parseInt(jTextFieldPort.getText());
                    SocketAddress address = new InetSocketAddress(port);

                    connection.connect(address);

                } catch (SocketException ex) {

                    ErrorHandler.errorWithPortMessage(mainPanel);
                    enableUI();
                    return null;
                } catch (IOException ex) {
                    Logger.getLogger(GameControllerServerView.class.getName()).log(Level.SEVERE, null, ex);
                }

            } else {
                try {
                    //Stop
                    connection.close();
                    container = null;
                    connection = null;
                } catch (IOException ex) {
                    Logger.getLogger(GameControllerServerView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }


            return null;  
        }

        @Override
        protected void succeeded(Object result) {
        }
    }

    private void enableUI() {
        serverStarted = false;
        jButtonStartServer.setText("Start Server");
        jButtonStartServer.setIcon(resourceMap.getIcon("jButtonStartServer.icon"));
        //Enable all buttons on Panels
        jPanelGameController.setEnabled(true);
        for (Component com : jPanelGameController.getComponents()) {
            com.setEnabled(true);

        }

        jPanelButtonContainer.setEnabled(true);
        for (Component com : jPanelButtonContainer.getComponents()) {
            com.setEnabled(true);
        }

        //Remove overlays
        jPanelGameController.remove(overlayGameControllerPanel);
        jPanelButtonContainer.remove(overlayButtonContainerPanel);
        jButtonStaticController.setEnabled(true);
        jPanelGameController.repaint();
        jPanelButtonContainer.repaint();

        //File Menu
        fileMenu.setEnabled(true);

        //Port text fiel
        jTextFieldPort.setEnabled(true);
        
    }

    private void disableUI() {
        //Button Container overlay
        overlayButtonContainerPanel = new GlassPanel(jPanelButtonContainer.getSize().width, jPanelButtonContainer.getSize().height);
        overlayButtonContainerPanel.setSize(jPanelButtonContainer.getSize().width, jPanelButtonContainer.getSize().height);
        overlayButtonContainerPanel.setOpaque(false);
        jPanelButtonContainer.add(overlayButtonContainerPanel, 0);

        //Game Controller overlay
        overlayGameControllerPanel = new GlassPanel(jPanelGameController.getSize().width, jPanelGameController.getSize().height);
        overlayGameControllerPanel.setSize(jPanelGameController.getSize().width, jPanelGameController.getSize().height);
        overlayGameControllerPanel.setOpaque(false);
        jPanelGameController.add(overlayGameControllerPanel, 0);

        //Disable all buttons on panels
        jPanelGameController.setEnabled(false);
        for (Component com : jPanelGameController.getComponents()) {
            com.setEnabled(false);
        }

        jPanelButtonContainer.setEnabled(false);
        for (Component com : jPanelButtonContainer.getComponents()) {
            com.setEnabled(false);
        }


        jPanelButtonContainer.repaint();
        jPanelGameController.repaint();
        serverStarted = true;
        jButtonStartServer.setText("Stop Server");

        //File Menu
        fileMenu.setEnabled(false);

        //Port text fiel
        jTextFieldPort.setEnabled(false);
        jButtonStartServer.setIcon(resourceMap.getIcon("jLabelServerStatusOnline.icon"));
    }

    @Action
    public void onNewControllerClicked() {
        jPanelGameController.removeAll();
        jPanelGameController.add(jPanelMenuPlaceholder);
        jPanelGameController.repaint();
    }

    @Action
    public void onSaveControllerClicked() {
        if (jPanelGameController.getComponentCount() < 2) {
            ErrorHandler.notEnoughButtonsMessage(mainPanel);
        } else {
            SaveOptionHandler optionFrame = SaveOptionHandler.getInstance();
            optionFrame.invokeSaveOptionFrame(jPanelGameController);
        }


    }

    @Action
    public void onLoadControllerClicked() {

        //Create a file chooser
        final JFileChooser fc = new JFileChooser();
        FileFilter filter1 = new ExtensionFileFilter("XML File", new String[]{"xml"});
        fc.setFileFilter(filter1);
        fc.showOpenDialog(mainPanel);

        File selFile = fc.getSelectedFile();
        if (selFile == null || !selFile.exists()) {
            return;
        }
        ControllerSerializer serializer = ControllerSerializer.getInstance();

        jPanelGameController.removeAll();
        jPanelGameController.repaint();
        List<ControllerElement> buttonList = null;
        try {
            buttonList = serializer.loadController(selFile);
        } catch (InvalidControllerException ex) {
            ErrorHandler.errorWhileLoadingMessage(mainPanel);
        }

        for (ControllerElement element : buttonList) {

            if (element instanceof RoundButtonBean) {
                RoundControllerButton roundButton = new RoundControllerButton(element.getLabel());
                roundButton.setLocation(element.getLx(), element.getLy());
                roundButton.setSize(element.getHeight(), element.getHeight());
                roundButton.setColor(((RoundButtonBean) element).getColor());
                roundButton.setTimeBetweePresses(((RoundButtonBean) element).getTimeBetweenPresses());
                roundButton.setButtonToPress(((RoundButtonBean) element).getButtonToPress());
                roundButton.setRepeatsPresses(((RoundButtonBean) element).isRepeatsPresses());
                roundButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                    @Override
                    public void mouseDragged(java.awt.event.MouseEvent evt) {

                        normalButtonOnGameControllerDragges(evt);


                    }
                });
                roundButton.addMouseListener(new java.awt.event.MouseListener() {

                    public void mouseClicked(MouseEvent e) {
                        jButtonRoundButtonMouseClicked(e);
                    }

                    public void mousePressed(MouseEvent e) {
                    }

                    public void mouseReleased(MouseEvent e) {
                    }

                    public void mouseEntered(MouseEvent e) {
                    }

                    public void mouseExited(MouseEvent e) {
                    }
                });
                jPanelGameController.add(roundButton);
            } else if (element instanceof ButtonBean) {

                NormalControllerButton normalButton = new NormalControllerButton();
                normalButton.setLocation(element.getLx(), element.getLy());
                normalButton.setText(element.getLabel());
                normalButton.setSize(element.getWidth(), element.getHeight());
                normalButton.setColor(element.getColor());
                normalButton.setOpaque(true);
                normalButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                    @Override
                    public void mouseDragged(java.awt.event.MouseEvent evt) {

                        normalButtonOnGameControllerDragges(evt);


                    }
                });
                normalButton.addMouseListener(new java.awt.event.MouseListener() {

                    public void mouseClicked(MouseEvent e) {
                        normalButtonOnGameControllerClicked(e);
                    }

                    public void mousePressed(MouseEvent e) {
                    }

                    public void mouseReleased(MouseEvent e) {
                    }

                    public void mouseEntered(MouseEvent e) {
                    }

                    public void mouseExited(MouseEvent e) {
                    }
                });
                jPanelGameController.add(normalButton);
            } else if (element instanceof JoystickBean) {

                StaticControllerButton controllerButton = new StaticControllerButton();

                controllerButton.setUpButton(((JoystickBean) element).getUpButton());
                controllerButton.setDownButton(((JoystickBean) element).getDownButton());
                controllerButton.setLeftButton(((JoystickBean) element).getLeftButton());
                controllerButton.setRightButton(((JoystickBean) element).getRightButton());
                controllerButton.setLocation(element.getLx(), element.getLy());
                controllerButton.setSize(element.getWidth(), element.getHeight());
                controllerButton.setColor(((JoystickBean) element).getColor());
                controllerButton.setOpaque(true);
                controllerButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                    @Override
                    public void mouseDragged(java.awt.event.MouseEvent evt) {
                        normalButtonOnGameControllerDragges(evt);
                    }
                });
                controllerButton.addMouseListener(new java.awt.event.MouseListener() {

                    public void mouseClicked(MouseEvent e) {
                        jButtonStaticControllerMouseClicked(e);
                    }

                    public void mousePressed(MouseEvent e) {
                    }

                    public void mouseReleased(MouseEvent e) {
                    }

                    public void mouseEntered(MouseEvent e) {
                    }

                    public void mouseExited(MouseEvent e) {
                    }
                });
                jPanelGameController.add(controllerButton);
            } else if (element instanceof MouseJoystickBean) {
                MouseJoystickButton mouseJoystickButton = new MouseJoystickButton();


                mouseJoystickButton.setLocation(element.getLx(), element.getLy());
                mouseJoystickButton.setSize(element.getWidth(), element.getHeight());
                mouseJoystickButton.setOpaque(true);
                mouseJoystickButton.setBorderPainted(false);
                mouseJoystickButton.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {

                    @Override
                    public void mouseDragged(java.awt.event.MouseEvent evt) {
                        normalButtonOnGameControllerDragges(evt);
                    }
                });
                mouseJoystickButton.addMouseListener(new java.awt.event.MouseListener() {

                    public void mouseClicked(MouseEvent e) {
                        jButtonMouseJoystickClicked(e);
                    }

                    public void mousePressed(MouseEvent e) {
                    }

                    public void mouseReleased(MouseEvent e) {
                    }

                    public void mouseEntered(MouseEvent e) {
                    }

                    public void mouseExited(MouseEvent e) {
                    }
                });
                jPanelGameController.add(mouseJoystickButton);
            }
        }


        jPanelGameController.add(jPanelMenuPlaceholder);
        jPanelGameController.repaint();

    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenu fileMenu;
    private javax.swing.JButton jButtonMouseJoystick;
    private javax.swing.JButton jButtonNormalButton;
    private javax.swing.JButton jButtonRoundButton;
    private javax.swing.JButton jButtonStartServer;
    private javax.swing.JButton jButtonStaticController;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabelLocalIP;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLayeredPane jPanelButtonContainer;
    private javax.swing.JLayeredPane jPanelGameController;
    private javax.swing.JPanel jPanelMenuPlaceholder;
    private javax.swing.JTextField jTextFieldLocalIP;
    private javax.swing.JTextField jTextFieldPort;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    // End of variables declaration//GEN-END:variables
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;
}
